using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Windows.Media;
using ASPItalia.ModelVirtualCasting.WPF.ViewModels;

namespace ASPItalia.ModelVirtualCasting.WPF.DragDrop
{
    /// <summary>
    /// Class that act as drag'n'drop source element manager for current ModelViewModel
    /// </summary>
    public class ModelDragSourceAdvisor : IDragSourceAdvisor
    {
        private UIElement _sourceUI;

        /// <summary>
        /// Get the effects (copy, move, ...) supported by this source
        /// </summary>
        public DragDropEffects SupportedEffects
        {
            get { return DragDropEffects.Copy | DragDropEffects.Move; }
        }

        /// <summary>
        /// Get the effects (copy, move, ...) supported by this source
        /// </summary>
        public UIElement SourceUI
        {
            get
            {
                return _sourceUI;
            }
            set
            {
                _sourceUI = value;
            }
        }

        /// <summary>
        /// Get the clipboard data to transfer from source to target
        /// </summary>
        /// <param name="draggedElt">Start dragging element</param>
        /// <param name="offsetPoint">Start dragging mouse position</param>
        /// <returns></returns>
        public DataObject GetDataObject(UIElement draggedElt, Point offsetPoint)
        {
            DataObject data = new DataObject();
            FrameworkElement uiItem = GetContainer(draggedElt);
            ModelViewModel item = ViewModelsContext.Current.MainViewModel.CurrentModel;
            data.SetData(DataFormats.Locale, uiItem);
            data.SetData(DataFormats.Serializable, item);
            data.SetData("point", offsetPoint);

            return data;
        }

        /// <summary>
        /// Called when drag'n'drop operation is finished
        /// </summary>
        /// <param name="draggedElt"></param>
        /// <param name="finalEffects"></param>
        public void FinishDrag(UIElement draggedElt, DragDropEffects finalEffects)
        {
        }

        /// <summary>
        /// Get if the start dragging element is valid for drag'n'drop operation
        /// </summary>
        /// <param name="draggedElt"></param>
        /// <returns></returns>
        public bool IsDraggable(UIElement draggedElt)
        {
            DependencyObject uiItem = GetContainer(draggedElt);
            return (uiItem != null);
        }

        private FrameworkElement GetContainer(UIElement dragElt)
        {
            DependencyObject parent = dragElt;
            while ((parent = VisualTreeHelper.GetParent(parent)) != null && !(parent is FrameworkElement) || ((FrameworkElement)parent).DataContext == null)
            { }

            return parent as FrameworkElement;
        }

    }
}
